package com.immediatus.graphics.camera;

import com.immediatus.engine.input.TouchEvent;

public class ZoomCamera extends BoundCamera{
    protected float _zoomFactor = 1.0f;

    public ZoomCamera(final float x_, final float y_, final float w_, final float h_){
        super(x_, y_, w_, h_);
    }

    public float getZoomFactor(){
        return this._zoomFactor;
    }

    public void setZoomFactor(final float zoomFactor_){
        this._zoomFactor = zoomFactor_;

        if (this.isBoundsEnabled()){
            this.ensureInBounds();
        }
    }

    @Override
    public float getMinX(){
        if (this._zoomFactor == 1.0f){
            return super.getMinX();
        } else{
            final float centerX = this.getCenterX();
            return centerX - (centerX - super.getMinX()) / this._zoomFactor;
        }
    }

    @Override
    public float getMaxX(){
        if (this._zoomFactor == 1.0f){
            return super.getMaxX();
        } else{
            final float centerX = this.getCenterX();
            return centerX + (super.getMaxX() - centerX) / this._zoomFactor;
        }
    }

    @Override
    public float getMinY(){
        if (this._zoomFactor == 1.0f){
            return super.getMinY();
        } else{
            final float centerY = this.getCenterY();
            return centerY - (centerY - super.getMinY()) / this._zoomFactor;
        }
    }

    @Override
    public float getMaxY(){
        if (this._zoomFactor == 1.0f){
            return super.getMaxY();
        } else{
            final float centerY = this.getCenterY();
            return centerY + (super.getMaxY() - centerY) / this._zoomFactor;
        }
    }

    @Override
    public float getWidth(){
        return super.getWidth() / this._zoomFactor;
    }

    @Override
    public float getHeight(){
        return super.getHeight() / this._zoomFactor;
    }

    @Override
    protected void applyLayerToCameraOffset(final TouchEvent touchEvent_){
        final float zoomFactor = this._zoomFactor;
        if (zoomFactor != 1){
            final float scaleCenterX = this.getCenterX();
            final float scaleCenterY = this.getCenterY();

            VERTICES_TOUCH_BUFFER[VERTEX_INDEX_X] = touchEvent_.getX();
            VERTICES_TOUCH_BUFFER[VERTEX_INDEX_Y] = touchEvent_.getY();

            scaleAroundCenter(VERTICES_TOUCH_BUFFER, zoomFactor, zoomFactor, scaleCenterX, scaleCenterY);

            touchEvent_.set(VERTICES_TOUCH_BUFFER[VERTEX_INDEX_X], VERTICES_TOUCH_BUFFER[VERTEX_INDEX_Y]);
        }
        super.applyLayerToCameraOffset(touchEvent_);
    }

    @Override
    protected void unapplyLayerToCameraOffset(final TouchEvent touchEvent_){
        super.unapplyLayerToCameraOffset(touchEvent_);

        final float zoomFactor = this._zoomFactor;
        if (zoomFactor != 1){
            final float scaleCenterX = this.getCenterX();
            final float scaleCenterY = this.getCenterY();

            VERTICES_TOUCH_BUFFER[VERTEX_INDEX_X] = touchEvent_.getX();
            VERTICES_TOUCH_BUFFER[VERTEX_INDEX_Y] = touchEvent_.getY();

            revertScaleAroundCenter(VERTICES_TOUCH_BUFFER, zoomFactor, zoomFactor, scaleCenterX, scaleCenterY);

            touchEvent_.set(VERTICES_TOUCH_BUFFER[VERTEX_INDEX_X], VERTICES_TOUCH_BUFFER[VERTEX_INDEX_Y]);
        }
    }
}
